home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet internetowy / Rozne / HTTrack 3.40-2 / httrack-3.40-2.exe / {app} / src / minizip / zip.c.orig < prev    next >
Text File  |  2004-01-18  |  38KB  |  1,181 lines

  1. /* zip.c -- IO on .zip files using zlib
  2.    Version 1.00, September 10th, 2003
  3.  
  4.    Copyright (C) 1998-2003 Gilles Vollant
  5.  
  6.    Read zip.h for more info
  7. */
  8.  
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include "zlib.h"
  15. #include "zip.h"
  16.  
  17. #ifdef STDC
  18. #  include <stddef.h>
  19. #  include <string.h>
  20. #  include <stdlib.h>
  21. #endif
  22. #ifdef NO_ERRNO_H
  23.     extern int errno;
  24. #else
  25. #   include <errno.h>
  26. #endif
  27.  
  28.  
  29. #ifndef local
  30. #  define local static
  31. #endif
  32. /* compile with -Dlocal if your debugger can't find static symbols */
  33.  
  34. #ifndef VERSIONMADEBY
  35. # define VERSIONMADEBY   (0x0) /* platform depedent */
  36. #endif
  37.  
  38. #ifndef Z_BUFSIZE
  39. #define Z_BUFSIZE (16384)
  40. #endif
  41.  
  42. #ifndef Z_MAXFILENAMEINZIP
  43. #define Z_MAXFILENAMEINZIP (256)
  44. #endif
  45.  
  46. #ifndef ALLOC
  47. # define ALLOC(size) (malloc(size))
  48. #endif
  49. #ifndef TRYFREE
  50. # define TRYFREE(p) {if (p) free(p);}
  51. #endif
  52.  
  53. /*
  54. #define SIZECENTRALDIRITEM (0x2e)
  55. #define SIZEZIPLOCALHEADER (0x1e)
  56. */
  57.  
  58. /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
  59.  
  60. #ifndef SEEK_CUR
  61. #define SEEK_CUR    1
  62. #endif
  63.  
  64. #ifndef SEEK_END
  65. #define SEEK_END    2
  66. #endif
  67.  
  68. #ifndef SEEK_SET
  69. #define SEEK_SET    0
  70. #endif
  71.  
  72. #ifndef DEF_MEM_LEVEL
  73. #if MAX_MEM_LEVEL >= 8
  74. #  define DEF_MEM_LEVEL 8
  75. #else
  76. #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
  77. #endif
  78. #endif
  79. const char zip_copyright[] =
  80.    " zip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll";
  81.  
  82.  
  83. #define SIZEDATA_INDATABLOCK (4096-(4*4))
  84.  
  85. #define LOCALHEADERMAGIC    (0x04034b50)
  86. #define CENTRALHEADERMAGIC  (0x02014b50)
  87. #define ENDHEADERMAGIC      (0x06054b50)
  88.  
  89. #define FLAG_LOCALHEADER_OFFSET (0x06)
  90. #define CRC_LOCALHEADER_OFFSET  (0x0e)
  91.  
  92. #define SIZECENTRALHEADER (0x2e) /* 46 */
  93.  
  94. typedef struct linkedlist_datablock_internal_s
  95. {
  96.   struct linkedlist_datablock_internal_s* next_datablock;
  97.   uLong  avail_in_this_block;
  98.   uLong  filled_in_this_block;
  99.   uLong  unused; /* for future use and alignement */
  100.   unsigned char data[SIZEDATA_INDATABLOCK];
  101. } linkedlist_datablock_internal;
  102.  
  103. typedef struct linkedlist_data_s
  104. {
  105.     linkedlist_datablock_internal* first_block;
  106.     linkedlist_datablock_internal* last_block;
  107. } linkedlist_data;
  108.  
  109.  
  110. typedef struct
  111. {
  112.     z_stream stream;            /* zLib stream structure for inflate */
  113.     int  stream_initialised;    /* 1 is stream is initialised */
  114.     uInt pos_in_buffered_data;  /* last written byte in buffered_data */
  115.  
  116.     uLong pos_local_header;     /* offset of the local header of the file
  117.                                      currenty writing */
  118.     char* central_header;       /* central header data for the current file */
  119.     uLong size_centralheader;   /* size of the central header for cur file */
  120.     uLong flag;                 /* flag of the file currently writing */
  121.  
  122.     int  method;                /* compression method of file currenty wr.*/
  123.     int  raw;                   /* 1 for directly writing raw data */
  124.     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
  125.     uLong dosDate;
  126.     uLong crc32;
  127.     int  encrypt;
  128. #ifndef NOCRYPT
  129.     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
  130.     const unsigned long* pcrc_32_tab;
  131.     int crypt_header_size;
  132. #endif
  133. } curfile_info;
  134.  
  135. typedef struct
  136. {
  137.     zlib_filefunc_def z_filefunc;
  138.     voidpf filestream;        /* io structore of the zipfile */
  139.     linkedlist_data central_dir;/* datablock with central dir in construction*/
  140.     int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
  141.     curfile_info ci;            /* info on the file curretly writing */
  142.  
  143.     uLong begin_pos;            /* position of the beginning of the zipfile */
  144.     uLong add_position_when_writting_offset;
  145.     uLong number_entry;
  146. } zip_internal;
  147.  
  148.  
  149.  
  150. #ifndef NOCRYPT
  151. #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
  152. #include "crypt.h"
  153. #endif
  154.  
  155. local linkedlist_datablock_internal* allocate_new_datablock()
  156. {
  157.     linkedlist_datablock_internal* ldi;
  158.     ldi = (linkedlist_datablock_internal*)
  159.                  ALLOC(sizeof(linkedlist_datablock_internal));
  160.     if (ldi!=NULL)
  161.     {
  162.         ldi->next_datablock = NULL ;
  163.         ldi->filled_in_this_block = 0 ;
  164.         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
  165.     }
  166.     return ldi;
  167. }
  168.  
  169. local void free_datablock(ldi)
  170.     linkedlist_datablock_internal* ldi;
  171. {
  172.     while (ldi!=NULL)
  173.     {
  174.         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
  175.         TRYFREE(ldi);
  176.         ldi = ldinext;
  177.     }
  178. }
  179.  
  180. local void init_linkedlist(ll)
  181.     linkedlist_data* ll;
  182. {
  183.     ll->first_block = ll->last_block = NULL;
  184. }
  185.  
  186. local void free_linkedlist(ll)
  187.     linkedlist_data* ll;
  188. {
  189.     free_datablock(ll->first_block);
  190.     ll->first_block = ll->last_block = NULL;
  191. }
  192.  
  193.  
  194. local int add_data_in_datablock(ll,buf,len)
  195.     linkedlist_data* ll;
  196.     const void* buf;
  197.     uLong len;
  198. {
  199.     linkedlist_datablock_internal* ldi;
  200.     const unsigned char* from_copy;
  201.  
  202.     if (ll==NULL)
  203.         return ZIP_INTERNALERROR;
  204.  
  205.     if (ll->last_block == NULL)
  206.     {
  207.         ll->first_block = ll->last_block = allocate_new_datablock();
  208.         if (ll->first_block == NULL)
  209.             return ZIP_INTERNALERROR;
  210.     }
  211.  
  212.     ldi = ll->last_block;
  213.     from_copy = (unsigned char*)buf;
  214.  
  215.     while (len>0)
  216.     {
  217.         uInt copy_this;
  218.         uInt i;
  219.         unsigned char* to_copy;
  220.  
  221.         if (ldi->avail_in_this_block==0)
  222.         {
  223.             ldi->next_datablock = allocate_new_datablock();
  224.             if (ldi->next_datablock == NULL)
  225.                 return ZIP_INTERNALERROR;
  226.             ldi = ldi->next_datablock ;
  227.             ll->last_block = ldi;
  228.         }
  229.  
  230.         if (ldi->avail_in_this_block < len)
  231.             copy_this = (uInt)ldi->avail_in_this_block;
  232.         else
  233.             copy_this = (uInt)len;
  234.  
  235.         to_copy = &(ldi->data[ldi->filled_in_this_block]);
  236.  
  237.         for (i=0;i<copy_this;i++)
  238.             *(to_copy+i)=*(from_copy+i);
  239.  
  240.         ldi->filled_in_this_block += copy_this;
  241.         ldi->avail_in_this_block -= copy_this;
  242.         from_copy += copy_this ;
  243.         len -= copy_this;
  244.     }
  245.     return ZIP_OK;
  246. }
  247.  
  248.  
  249.  
  250. /****************************************************************************/
  251.  
  252. #ifndef NO_ADDFILEINEXISTINGZIP
  253. /* ===========================================================================
  254.    Inputs a long in LSB order to the given file
  255.    nbByte == 1, 2 or 4 (byte, short or long)
  256. */
  257.  
  258. local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
  259.                                 voidpf filestream, uLong x, int nbByte));
  260. local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
  261.     const zlib_filefunc_def* pzlib_filefunc_def;
  262.     voidpf filestream;
  263.     uLong x;
  264.     int nbByte;
  265. {
  266.     unsigned char buf[4];
  267.     int n;
  268.     for (n = 0; n < nbByte; n++) {
  269.         buf[n] = (unsigned char)(x & 0xff);
  270.         x >>= 8;
  271.     }
  272.     if (x != 0) {     // data overflow - hack for ZIP64
  273.       for (n = 0; n < nbByte; n++) {
  274.         buf[n] = 0xff;
  275.       }
  276.     }
  277.    if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
  278.         return ZIP_ERRNO;
  279.     else
  280.         return ZIP_OK;
  281. }
  282.  
  283. local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
  284. local void ziplocal_putValue_inmemory (dest, x, nbByte)
  285.     void* dest;
  286.     uLong x;
  287.     int nbByte;
  288. {
  289.     unsigned char* buf=(unsigned char*)dest;
  290.     int n;
  291.     for (n = 0; n < nbByte; n++) {
  292.         buf[n] = (unsigned char)(x & 0xff);
  293.         x >>= 8;
  294.     }
  295.     if (x != 0) {     // data overflow - hack for ZIP64
  296.       for (n = 0; n < nbByte; n++) {
  297.         buf[n] = 0xff;
  298.       }
  299.     }
  300. }
  301. /****************************************************************************/
  302.  
  303.  
  304. local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
  305.     const tm_zip* ptm;
  306.     uLong dosDate;
  307. {
  308.     uLong year = (uLong)ptm->tm_year;
  309.     if (year>1980)
  310.         year-=1980;
  311.     else if (year>80)
  312.         year-=80;
  313.     return
  314.       (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
  315.         ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
  316. }
  317.  
  318.  
  319. /****************************************************************************/
  320.  
  321. local int ziplocal_getByte OF((
  322.     const zlib_filefunc_def* pzlib_filefunc_def,
  323.     voidpf filestream,
  324.     int *pi));
  325.  
  326. local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
  327.     const zlib_filefunc_def* pzlib_filefunc_def;
  328.     voidpf filestream;
  329.     int *pi;
  330. {
  331.     unsigned char c;
  332.     int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
  333.     if (err==1)
  334.     {
  335.         *pi = (int)c;
  336.         return ZIP_OK;
  337.     }
  338.     else
  339.     {
  340.         if (ZERROR(*pzlib_filefunc_def,filestream))
  341.             return ZIP_ERRNO;
  342.         else
  343.             return ZIP_EOF;
  344.     }
  345. }
  346.  
  347.  
  348. /* ===========================================================================
  349.    Reads a long in LSB order from the given gz_stream. Sets
  350. */
  351. local int ziplocal_getShort OF((
  352.     const zlib_filefunc_def* pzlib_filefunc_def,
  353.     voidpf filestream,
  354.     uLong *pX));
  355.  
  356. local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
  357.     const zlib_filefunc_def* pzlib_filefunc_def;
  358.     voidpf filestream;
  359.     uLong *pX;
  360. {
  361.     uLong x ;
  362.     int i;
  363.     int err;
  364.  
  365.     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  366.     x = (uLong)i;
  367.  
  368.     if (err==ZIP_OK)
  369.         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  370.     x += ((uLong)i)<<8;
  371.  
  372.     if (err==ZIP_OK)
  373.         *pX = x;
  374.     else
  375.         *pX = 0;
  376.     return err;
  377. }
  378.  
  379. local int ziplocal_getLong OF((
  380.     const zlib_filefunc_def* pzlib_filefunc_def,
  381.     voidpf filestream,
  382.     uLong *pX));
  383.  
  384. local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
  385.     const zlib_filefunc_def* pzlib_filefunc_def;
  386.     voidpf filestream;
  387.     uLong *pX;
  388. {
  389.     uLong x ;
  390.     int i;
  391.     int err;
  392.  
  393.     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  394.     x = (uLong)i;
  395.  
  396.     if (err==ZIP_OK)
  397.         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  398.     x += ((uLong)i)<<8;
  399.  
  400.     if (err==ZIP_OK)
  401.         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  402.     x += ((uLong)i)<<16;
  403.  
  404.     if (err==ZIP_OK)
  405.         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  406.     x += ((uLong)i)<<24;
  407.  
  408.     if (err==ZIP_OK)
  409.         *pX = x;
  410.     else
  411.         *pX = 0;
  412.     return err;
  413. }
  414.  
  415. #ifndef BUFREADCOMMENT
  416. #define BUFREADCOMMENT (0x400)
  417. #endif
  418. /*
  419.   Locate the Central directory of a zipfile (at the end, just before
  420.     the global comment)
  421. */
  422. local uLong ziplocal_SearchCentralDir OF((
  423.     const zlib_filefunc_def* pzlib_filefunc_def,
  424.     voidpf filestream));
  425.  
  426. local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
  427.     const zlib_filefunc_def* pzlib_filefunc_def;
  428.     voidpf filestream;
  429. {
  430.     unsigned char* buf;
  431.     uLong uSizeFile;
  432.     uLong uBackRead;
  433.     uLong uMaxBack=0xffff; /* maximum size of global comment */
  434.     uLong uPosFound=0;
  435.  
  436.     if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  437.         return 0;
  438.  
  439.  
  440.     uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
  441.  
  442.     if (uMaxBack>uSizeFile)
  443.         uMaxBack = uSizeFile;
  444.  
  445.     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  446.     if (buf==NULL)
  447.         return 0;
  448.  
  449.     uBackRead = 4;
  450.     while (uBackRead<uMaxBack)
  451.     {
  452.         uLong uReadSize,uReadPos ;
  453.         int i;
  454.         if (uBackRead+BUFREADCOMMENT>uMaxBack)
  455.             uBackRead = uMaxBack;
  456.         else
  457.             uBackRead+=BUFREADCOMMENT;
  458.         uReadPos = uSizeFile-uBackRead ;
  459.  
  460.         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  461.                      (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
  462.         if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  463.             break;
  464.  
  465.         if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  466.             break;
  467.  
  468.         for (i=(int)uReadSize-3; (i--)>0;)
  469.             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
  470.                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
  471.             {
  472.                 uPosFound = uReadPos+i;
  473.                 break;
  474.             }
  475.  
  476.         if (uPosFound!=0)
  477.             break;
  478.     }
  479.     TRYFREE(buf);
  480.     return uPosFound;
  481. }
  482. #endif /* !NO_ADDFILEINEXISTINGZIP*/
  483.  
  484. /************************************************************/
  485. extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
  486.     const char *pathname;
  487.     int append;
  488.     zipcharpc* globalcomment;
  489.     zlib_filefunc_def* pzlib_filefunc_def;
  490. {
  491.     zip_internal ziinit;
  492.     zip_internal* zi;
  493.     int err=ZIP_OK;
  494.  
  495.  
  496.     if (pzlib_filefunc_def==NULL)
  497.         fill_fopen_filefunc(&ziinit.z_filefunc);
  498.     else
  499.         ziinit.z_filefunc = *pzlib_filefunc_def;
  500.  
  501.     ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
  502.                  (ziinit.z_filefunc.opaque,
  503.                   pathname,
  504.                   (append == APPEND_STATUS_CREATE) ?
  505.                   (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
  506.                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
  507.  
  508.     if (ziinit.filestream == NULL)
  509.         return NULL;
  510.     ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
  511.     ziinit.in_opened_file_inzip = 0;
  512.     ziinit.ci.stream_initialised = 0;
  513.     ziinit.number_entry = 0;
  514.     ziinit.add_position_when_writting_offset = 0;
  515.     init_linkedlist(&(ziinit.central_dir));
  516.  
  517.  
  518.     zi = (zip_internal*)ALLOC(sizeof(zip_internal));
  519.     if (zi==NULL)
  520.     {
  521.         ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
  522.         return NULL;
  523.     }
  524.  
  525.     /* now we add file in a zipfile */
  526. #    ifndef NO_ADDFILEINEXISTINGZIP
  527.     if (append == APPEND_STATUS_ADDINZIP)
  528.     {
  529.         uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
  530.  
  531.         uLong size_central_dir;     /* size of the central directory  */
  532.         uLong offset_central_dir;   /* offset of start of central directory */
  533.         uLong central_pos,uL;
  534.  
  535.         uLong number_disk;          /* number of the current dist, used for
  536.                                     spaning ZIP, unsupported, always 0*/
  537.         uLong number_disk_with_CD;  /* number the the disk with central dir, used
  538.                                     for spaning ZIP, unsupported, always 0*/
  539.         uLong number_entry;
  540.         uLong number_entry_CD;      /* total number of entries in
  541.                                     the central dir
  542.                                     (same than number_entry on nospan) */
  543.         uLong size_comment;
  544.  
  545.         central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
  546.         if (central_pos==0)
  547.             err=ZIP_ERRNO;
  548.  
  549.         if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
  550.                                         central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  551.             err=ZIP_ERRNO;
  552.  
  553.         /* the signature, already checked */
  554.         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
  555.             err=ZIP_ERRNO;
  556.  
  557.         /* number of this disk */
  558.         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
  559.             err=ZIP_ERRNO;
  560.  
  561.         /* number of the disk with the start of the central directory */
  562.         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
  563.             err=ZIP_ERRNO;
  564.  
  565.         /* total number of entries in the central dir on this disk */
  566.         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
  567.             err=ZIP_ERRNO;
  568.  
  569.         /* total number of entries in the central dir */
  570.         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
  571.             err=ZIP_ERRNO;
  572.  
  573.         if ((number_entry_CD!=number_entry) ||
  574.             (number_disk_with_CD!=0) ||
  575.             (number_disk!=0))
  576.             err=ZIP_BADZIPFILE;
  577.  
  578.         /* size of the central directory */
  579.         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
  580.             err=ZIP_ERRNO;
  581.  
  582.         /* offset of start of central directory with respect to the
  583.             starting disk number */
  584.         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
  585.             err=ZIP_ERRNO;
  586.  
  587.         /* zipfile comment length */
  588.         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
  589.             err=ZIP_ERRNO;
  590.  
  591.         if ((central_pos<offset_central_dir+size_central_dir) &&
  592.             (err==ZIP_OK))
  593.             err=ZIP_BADZIPFILE;
  594.  
  595.         if (err!=ZIP_OK)
  596.         {
  597.             ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
  598.             return NULL;
  599.         }
  600.  
  601.         byte_before_the_zipfile = central_pos -
  602.                                 (offset_central_dir+size_central_dir);
  603.         ziinit.add_position_when_writting_offset = byte_before_the_zipfile ;
  604.  
  605.         {
  606.             uLong size_central_dir_to_read = size_central_dir;
  607.             size_t buf_size = SIZEDATA_INDATABLOCK;
  608.             void* buf_read = (void*)ALLOC(buf_size);
  609.             if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
  610.                   offset_central_dir + byte_before_the_zipfile,
  611.                   ZLIB_FILEFUNC_SEEK_SET) != 0)
  612.                   err=ZIP_ERRNO;
  613.  
  614.             while ((size_central_dir_to_read>0) && (err==ZIP_OK))
  615.             {
  616.                 uLong read_this = SIZEDATA_INDATABLOCK;
  617.                 if (read_this > size_central_dir_to_read)
  618.                     read_this = size_central_dir_to_read;
  619.                 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
  620.                     err=ZIP_ERRNO;
  621.  
  622.                 if (err==ZIP_OK)
  623.                     err = add_data_in_datablock(&ziinit.central_dir,buf_read,
  624.                                                 (uLong)read_this);
  625.                 size_central_dir_to_read-=read_this;
  626.             }
  627.             TRYFREE(buf_read);
  628.         }
  629.         ziinit.begin_pos = byte_before_the_zipfile;
  630.         ziinit.number_entry = number_entry_CD;
  631.  
  632.         if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
  633.                   offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
  634.             err=ZIP_ERRNO;
  635.     }
  636. #    endif /* !NO_ADDFILEINEXISTINGZIP*/
  637.  
  638.     if (err != ZIP_OK)
  639.     {
  640.         TRYFREE(zi);
  641.         return NULL;
  642.     }
  643.     else
  644.     {
  645.         *zi = ziinit;
  646.         return (zipFile)zi;
  647.     }
  648. }
  649.  
  650. extern zipFile ZEXPORT zipOpen (pathname, append)
  651.     const char *pathname;
  652.     int append;
  653. {
  654.     return zipOpen2(pathname,append,NULL,NULL);
  655. }
  656.  
  657. extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
  658.                                          extrafield_local, size_extrafield_local,
  659.                                          extrafield_global, size_extrafield_global,
  660.                                          comment, method, level, raw,
  661.                                          windowBits, memLevel, strategy,
  662.                                          password, crcForCrypting)
  663.     zipFile file;
  664.     const char* filename;
  665.     const zip_fileinfo* zipfi;
  666.     const void* extrafield_local;
  667.     uInt size_extrafield_local;
  668.     const void* extrafield_global;
  669.     uInt size_extrafield_global;
  670.     const char* comment;
  671.     int method;
  672.     int level;
  673.     int raw;
  674.     int windowBits;
  675.     int memLevel;
  676.     int strategy;
  677.     const char* password;
  678.     uLong crcForCrypting;
  679. {
  680.     zip_internal* zi;
  681.     uInt size_filename;
  682.     uInt size_comment;
  683.     uInt i;
  684.     int err = ZIP_OK;
  685.  
  686. #    ifdef NOCRYPT
  687.     if (password != NULL)
  688.         return ZIP_PARAMERROR;
  689. #    endif
  690.  
  691.     if (file == NULL)
  692.         return ZIP_PARAMERROR;
  693.     if ((method!=0) && (method!=Z_DEFLATED))
  694.         return ZIP_PARAMERROR;
  695.  
  696.     zi = (zip_internal*)file;
  697.  
  698.     if (zi->in_opened_file_inzip == 1)
  699.     {
  700.         err = zipCloseFileInZip (file);
  701.         if (err != ZIP_OK)
  702.             return err;
  703.     }
  704.  
  705.  
  706.     if (filename==NULL)
  707.         filename="-";
  708.  
  709.     if (comment==NULL)
  710.         size_comment = 0;
  711.     else
  712.         size_comment = strlen(comment);
  713.  
  714.     size_filename = strlen(filename);
  715.  
  716.     if (zipfi == NULL)
  717.         zi->ci.dosDate = 0;
  718.     else
  719.     {
  720.         if (zipfi->dosDate != 0)
  721.             zi->ci.dosDate = zipfi->dosDate;
  722.         else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
  723.     }
  724.  
  725.     zi->ci.flag = 0;
  726.     if ((level==8) || (level==9))
  727.       zi->ci.flag |= 2;
  728.     if ((level==2))
  729.       zi->ci.flag |= 4;
  730.     if ((level==1))
  731.       zi->ci.flag |= 6;
  732.     if (password != NULL)
  733.       zi->ci.flag |= 1;
  734.  
  735.     zi->ci.crc32 = 0;
  736.     zi->ci.method = method;
  737.     zi->ci.encrypt = 0;
  738.     zi->ci.stream_initialised = 0;
  739.     zi->ci.pos_in_buffered_data = 0;
  740.     zi->ci.raw = raw;
  741.     zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
  742.     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
  743.                                       size_extrafield_global + size_comment;
  744.     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
  745.  
  746.     ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
  747.     /* version info */
  748.     ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
  749.     ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
  750.     ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
  751.     ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
  752.     ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
  753.     ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
  754.     ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
  755.     ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
  756.     ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
  757.     ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
  758.     ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
  759.     ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
  760.  
  761.     if (zipfi==NULL)
  762.         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
  763.     else
  764.         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
  765.  
  766.     if (zipfi==NULL)
  767.         ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
  768.     else
  769.         ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
  770.  
  771.     ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
  772.  
  773.     for (i=0;i<size_filename;i++)
  774.         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
  775.  
  776.     for (i=0;i<size_extrafield_global;i++)
  777.         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
  778.               *(((const char*)extrafield_global)+i);
  779.  
  780.     for (i=0;i<size_comment;i++)
  781.         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
  782.               size_extrafield_global+i) = *(comment+i);
  783.     if (zi->ci.central_header == NULL)
  784.         return ZIP_INTERNALERROR;
  785.  
  786.     /* write the local header */
  787.     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
  788.  
  789.     if (err==ZIP_OK)
  790.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
  791.     if (err==ZIP_OK)
  792.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
  793.  
  794.     if (err==ZIP_OK)
  795.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
  796.  
  797.     if (err==ZIP_OK)
  798.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
  799.  
  800.     if (err==ZIP_OK)
  801.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
  802.     if (err==ZIP_OK)
  803.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
  804.     if (err==ZIP_OK)
  805.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
  806.  
  807.     if (err==ZIP_OK)
  808.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
  809.  
  810.     if (err==ZIP_OK)
  811.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
  812.  
  813.     if ((err==ZIP_OK) && (size_filename>0))
  814.         if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
  815.                 err = ZIP_ERRNO;
  816.  
  817.     if ((err==ZIP_OK) && (size_extrafield_local>0))
  818.         if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
  819.                                                                            !=size_extrafield_local)
  820.                 err = ZIP_ERRNO;
  821.  
  822.     zi->ci.stream.avail_in = (uInt)0;
  823.     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  824.     zi->ci.stream.next_out = zi->ci.buffered_data;
  825.     zi->ci.stream.total_in = 0;
  826.     zi->ci.stream.total_out = 0;
  827.  
  828.     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  829.     {
  830.         zi->ci.stream.zalloc = (alloc_func)0;
  831.         zi->ci.stream.zfree = (free_func)0;
  832.         zi->ci.stream.opaque = (voidpf)0;
  833.  
  834.         if (windowBits>0)
  835.             windowBits = -windowBits;
  836.  
  837.         err = deflateInit2(&zi->ci.stream, level,
  838.                Z_DEFLATED, windowBits, memLevel, strategy);
  839.  
  840.         if (err==Z_OK)
  841.             zi->ci.stream_initialised = 1;
  842.     }
  843. #    ifndef NOCRYPT
  844.     zi->ci.crypt_header_size = 0;
  845.     if ((err==Z_OK) && (password != NULL))
  846.     {
  847.         unsigned char bufHead[RAND_HEAD_LEN];
  848.         unsigned int sizeHead;
  849.         zi->ci.encrypt = 1;
  850.         zi->ci.pcrc_32_tab = get_crc_table();
  851.         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
  852.  
  853.         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
  854.         zi->ci.crypt_header_size = sizeHead;
  855.  
  856.         if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
  857.                 err = ZIP_ERRNO;
  858.     }
  859. #    endif
  860.  
  861.     if (err==Z_OK)
  862.         zi->in_opened_file_inzip = 1;
  863.     return err;
  864. }
  865.  
  866. extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
  867.                                         extrafield_local, size_extrafield_local,
  868.                                         extrafield_global, size_extrafield_global,
  869.                                         comment, method, level, raw)
  870.     zipFile file;
  871.     const char* filename;
  872.     const zip_fileinfo* zipfi;
  873.     const void* extrafield_local;
  874.     uInt size_extrafield_local;
  875.     const void* extrafield_global;
  876.     uInt size_extrafield_global;
  877.     const char* comment;
  878.     int method;
  879.     int level;
  880.     int raw;
  881. {
  882.     return zipOpenNewFileInZip3 (file, filename, zipfi,
  883.                                  extrafield_local, size_extrafield_local,
  884.                                  extrafield_global, size_extrafield_global,
  885.                                  comment, method, level, raw,
  886.                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  887.                                  NULL, 0);
  888. }
  889.  
  890. extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
  891.                                         extrafield_local, size_extrafield_local,
  892.                                         extrafield_global, size_extrafield_global,
  893.                                         comment, method, level)
  894.     zipFile file;
  895.     const char* filename;
  896.     const zip_fileinfo* zipfi;
  897.     const void* extrafield_local;
  898.     uInt size_extrafield_local;
  899.     const void* extrafield_global;
  900.     uInt size_extrafield_global;
  901.     const char* comment;
  902.     int method;
  903.     int level;
  904. {
  905.     return zipOpenNewFileInZip2 (file, filename, zipfi,
  906.                                  extrafield_local, size_extrafield_local,
  907.                                  extrafield_global, size_extrafield_global,
  908.                                  comment, method, level, 0);
  909. }
  910.  
  911. local int zipFlushWriteBuffer(zi)
  912.   zip_internal* zi;
  913. {
  914.     int err=ZIP_OK;
  915.  
  916.     if (zi->ci.encrypt != 0)
  917.     {
  918. #ifndef NOCRYPT
  919.         uInt i;
  920.         int t;
  921.         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
  922.             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
  923.                                        zi->ci.buffered_data[i],t);
  924. #endif
  925.     }
  926.     if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
  927.                                                                     !=zi->ci.pos_in_buffered_data)
  928.       err = ZIP_ERRNO;
  929.     zi->ci.pos_in_buffered_data = 0;
  930.     return err;
  931. }
  932.  
  933. extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
  934.     zipFile file;
  935.     const void* buf;
  936.     unsigned len;
  937. {
  938.     zip_internal* zi;
  939.     int err=ZIP_OK;
  940.  
  941.     if (file == NULL)
  942.         return ZIP_PARAMERROR;
  943.     zi = (zip_internal*)file;
  944.  
  945.     if (zi->in_opened_file_inzip == 0)
  946.         return ZIP_PARAMERROR;
  947.  
  948.     zi->ci.stream.next_in = (void*)buf;
  949.     zi->ci.stream.avail_in = len;
  950.     zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
  951.  
  952.     while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
  953.     {
  954.         if (zi->ci.stream.avail_out == 0)
  955.         {
  956.             if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
  957.                 err = ZIP_ERRNO;
  958.             zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  959.             zi->ci.stream.next_out = zi->ci.buffered_data;
  960.         }
  961.  
  962.  
  963.         if(err != ZIP_OK)
  964.             break;
  965.  
  966.         if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  967.         {
  968.             uLong uTotalOutBefore = zi->ci.stream.total_out;
  969.             err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
  970.             zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  971.  
  972.         }
  973.         else
  974.         {
  975.             uInt copy_this,i;
  976.             if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
  977.                 copy_this = zi->ci.stream.avail_in;
  978.             else
  979.                 copy_this = zi->ci.stream.avail_out;
  980.             for (i=0;i<copy_this;i++)
  981.                 *(((char*)zi->ci.stream.next_out)+i) =
  982.                     *(((const char*)zi->ci.stream.next_in)+i);
  983.             {
  984.                 zi->ci.stream.avail_in -= copy_this;
  985.                 zi->ci.stream.avail_out-= copy_this;
  986.                 zi->ci.stream.next_in+= copy_this;
  987.                 zi->ci.stream.next_out+= copy_this;
  988.                 zi->ci.stream.total_in+= copy_this;
  989.                 zi->ci.stream.total_out+= copy_this;
  990.                 zi->ci.pos_in_buffered_data += copy_this;
  991.             }
  992.         }
  993.     }
  994.  
  995.     return err;
  996. }
  997.  
  998. extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
  999.     zipFile file;
  1000.     uLong uncompressed_size;
  1001.     uLong crc32;
  1002. {
  1003.     zip_internal* zi;
  1004.     uLong compressed_size;
  1005.     int err=ZIP_OK;
  1006.  
  1007.     if (file == NULL)
  1008.         return ZIP_PARAMERROR;
  1009.     zi = (zip_internal*)file;
  1010.  
  1011.     if (zi->in_opened_file_inzip == 0)
  1012.         return ZIP_PARAMERROR;
  1013.     zi->ci.stream.avail_in = 0;
  1014.  
  1015.     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  1016.         while (err==ZIP_OK)
  1017.     {
  1018.         uLong uTotalOutBefore;
  1019.         if (zi->ci.stream.avail_out == 0)
  1020.         {
  1021.             if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
  1022.                 err = ZIP_ERRNO;
  1023.             zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1024.             zi->ci.stream.next_out = zi->ci.buffered_data;
  1025.         }
  1026.         uTotalOutBefore = zi->ci.stream.total_out;
  1027.         err=deflate(&zi->ci.stream,  Z_FINISH);
  1028.         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  1029.     }
  1030.  
  1031.     if (err==Z_STREAM_END)
  1032.         err=ZIP_OK; /* this is normal */
  1033.  
  1034.     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
  1035.         if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
  1036.             err = ZIP_ERRNO;
  1037.  
  1038.     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  1039.     {
  1040.         err=deflateEnd(&zi->ci.stream);
  1041.         zi->ci.stream_initialised = 0;
  1042.     }
  1043.  
  1044.     if (!zi->ci.raw)
  1045.     {
  1046.         crc32 = (uLong)zi->ci.crc32;
  1047.         uncompressed_size = (uLong)zi->ci.stream.total_in;
  1048.     }
  1049.     compressed_size = (uLong)zi->ci.stream.total_out;
  1050. #    ifndef NOCRYPT
  1051.     compressed_size += zi->ci.crypt_header_size;
  1052. #    endif
  1053.  
  1054.     ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
  1055.     ziplocal_putValue_inmemory(zi->ci.central_header+20,
  1056.                                 compressed_size,4); /*compr size*/
  1057.     if (zi->ci.stream.data_type == Z_ASCII)
  1058.         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
  1059.     ziplocal_putValue_inmemory(zi->ci.central_header+24,
  1060.                                 uncompressed_size,4); /*uncompr size*/
  1061.  
  1062.     if (err==ZIP_OK)
  1063.         err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
  1064.                                        (uLong)zi->ci.size_centralheader);
  1065.     free(zi->ci.central_header);
  1066.  
  1067.     if (err==ZIP_OK)
  1068.     {
  1069.         long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
  1070.         if (ZSEEK(zi->z_filefunc,zi->filestream,
  1071.                   zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
  1072.             err = ZIP_ERRNO;
  1073.  
  1074.         if (err==ZIP_OK)
  1075.             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
  1076.  
  1077.         if (err==ZIP_OK) /* compressed size, unknown */
  1078.             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
  1079.  
  1080.         if (err==ZIP_OK) /* uncompressed size, unknown */
  1081.             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
  1082.  
  1083.         if (ZSEEK(zi->z_filefunc,zi->filestream,
  1084.                   cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
  1085.             err = ZIP_ERRNO;
  1086.     }
  1087.  
  1088.     zi->number_entry ++;
  1089.     zi->in_opened_file_inzip = 0;
  1090.  
  1091.     return err;
  1092. }
  1093.  
  1094. extern int ZEXPORT zipCloseFileInZip (file)
  1095.     zipFile file;
  1096. {
  1097.     return zipCloseFileInZipRaw (file,0,0);
  1098. }
  1099.  
  1100. extern int ZEXPORT zipClose (file, global_comment)
  1101.     zipFile file;
  1102.     const char* global_comment;
  1103. {
  1104.     zip_internal* zi;
  1105.     int err = 0;
  1106.     uLong size_centraldir = 0;
  1107.     uLong centraldir_pos_inzip ;
  1108.     uInt size_global_comment;
  1109.     if (file == NULL)
  1110.         return ZIP_PARAMERROR;
  1111.     zi = (zip_internal*)file;
  1112.  
  1113.     if (zi->in_opened_file_inzip == 1)
  1114.     {
  1115.         err = zipCloseFileInZip (file);
  1116.     }
  1117.  
  1118.     if (global_comment==NULL)
  1119.         size_global_comment = 0;
  1120.     else
  1121.         size_global_comment = strlen(global_comment);
  1122.  
  1123.  
  1124.     centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
  1125.     if (err==ZIP_OK)
  1126.     {
  1127.         linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
  1128.         while (ldi!=NULL)
  1129.         {
  1130.             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
  1131.                 if (ZWRITE(zi->z_filefunc,zi->filestream,
  1132.                            ldi->data,ldi->filled_in_this_block)
  1133.                               !=ldi->filled_in_this_block )
  1134.                     err = ZIP_ERRNO;
  1135.  
  1136.             size_centraldir += ldi->filled_in_this_block;
  1137.             ldi = ldi->next_datablock;
  1138.         }
  1139.     }
  1140.     free_datablock(zi->central_dir.first_block);
  1141.  
  1142.     if (err==ZIP_OK) /* Magic End */
  1143.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
  1144.  
  1145.     if (err==ZIP_OK) /* number of this disk */
  1146.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  1147.  
  1148.     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  1149.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  1150.  
  1151.     if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
  1152.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  1153.  
  1154.     if (err==ZIP_OK) /* total number of entries in the central dir */
  1155.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  1156.  
  1157.     if (err==ZIP_OK) /* size of the central directory */
  1158.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
  1159.  
  1160.     if (err==ZIP_OK) /* offset of start of central directory with respect to the
  1161.                             starting disk number */
  1162.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
  1163.                                 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
  1164.  
  1165.     if (err==ZIP_OK) /* zipfile comment length */
  1166.         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
  1167.  
  1168.     if ((err==ZIP_OK) && (size_global_comment>0))
  1169.         if (ZWRITE(zi->z_filefunc,zi->filestream,
  1170.                    global_comment,size_global_comment) != size_global_comment)
  1171.                 err = ZIP_ERRNO;
  1172.  
  1173.     if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
  1174.         if (err == ZIP_OK)
  1175.             err = ZIP_ERRNO;
  1176.  
  1177.     TRYFREE(zi);
  1178.  
  1179.     return err;
  1180. }
  1181.